#include <getopt.h>
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "node.h"
#include "definitions.h"

using namespace std;

int main(int argc, char **argv) {
	int opt;
	int long_index;

	nodeOptions data;
	data.m = -1;
	data.id = -1;
	data.port = -1;
	data.introducerPort = -1;
	data.stabilizeInterval = -1;
	data.fixInterval = -1;
	data.seed = -1;
	data.logconffile = NULL;

	struct option long_options[] = {
		//required
		{"m", required_argument, 0, 1000},
		{"id", required_argument, 0, 1001},
		{"port", required_argument, 0, 1002},
		//optional
		{"introducerPort", required_argument, 0, 1003},
		{"logConf", required_argument, 0, 1004},
		{"stabilizeInterval", required_argument, 0, 1005},
		{"fixInterval", required_argument, 0, 1006},
		{"seed", required_argument, 0, 1007},
		{0, 0, 0, 0},
	};

	while ((opt = getopt_long(argc, argv, "", long_options, &long_index)) != -1)
	{
		switch (opt) {
			case 0:
				if (long_options[long_index].flag != 0) {
					break;
				}
				printf("option %s ", long_options[long_index].name);
				if (optarg) {
					printf("with arg %s\n", optarg);
				}
				printf("\n");
				break;

			case 1000:
				data.m = strtol(optarg, NULL, 10);
				break;

			case 1001:
				data.id = strtol(optarg, NULL, 10);
				break;

			case 1002:
				data.port = strtol(optarg, NULL, 10);
				break;

			case 1003:
				data.introducerPort = strtol(optarg, NULL, 10);
				assert(data.introducerPort > 0);
				break;

			case 1004:
				data.logconffile = optarg;
				break;

			case 1005:
				data.stabilizeInterval = strtol(optarg, NULL, 10);
				assert(data.stabilizeInterval > 0);
				break;

			case 1006:
				data.fixInterval = strtol(optarg, NULL, 10);
				assert(data.fixInterval > 0);
				break;

			case 1007:
				data.seed = strtol(optarg, NULL, 10);
				break;

			default:
				exit(1);
		}
	}

	assert((data.m >= 3) && (data.m <= 10));
	assert((data.id >= 0) && (data.id < (int)pow((double)2,(double)data.m)));
	assert (data.port > 0);
	if(data.seed <= 0)
	{
		srand(time(NULL));
	}
	else
	{
		srand(data.seed);
	}
	if(data.fixInterval <= 0)
	{
		data.fixInterval = 3;
	}
	if(data.stabilizeInterval <= 0)
	{
		data.stabilizeInterval = 3;
	}

	NodeApp node(data);
}
